package org.club.Service.impl;

import lombok.extern.slf4j.Slf4j;

import org.club.Service.IWebSocketService;
import org.club.common.WebSocket.WebSocketMessage;
import org.club.common.model.entity.BusinessException;
import org.club.common.util.ApiResponseMe;
import org.club.mapper.AnnouncementMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class WebSocketServiceImpl implements IWebSocketService {

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    @Autowired
    private AnnouncementMapper announcementMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<ApiResponseMe> handleMessage(WebSocketMessage message, SimpMessageHeaderAccessor headerAccessor) {
        String user = headerAccessor.getUser() != null ? headerAccessor.getUser().getName() : "anonymous";
        log.info("用户标识: {}", user);

        // 验证发送者身份
        if (!"anonymous".equals(user) && user.matches("\\d+")) {
            message.setSenderId(Long.parseLong(user));
        } else {
            log.warn("用户标识无效，无法设置发送者ID");
            throw new BusinessException(401, "发送者身份验证失败，请重新登录");
        }

        // 验证消息内容
        if (message.getContent() == null || message.getContent().trim().isEmpty()) {
            throw new BusinessException(400, "消息内容不能为空");
        }

        message.setSendTime(LocalDateTime.now());

        try {
            // 广播模式
            if (message.getReceiverIds() == null || message.getReceiverIds().isEmpty()) {
                log.info("广播消息: {}", message.getContent());
                // 创建关联
                // 获取所有的用户ID
                List<Long> receiverIds = announcementMapper.getUserIdCondition();
                // 剔除系统管理员的用户ID和发布者的ID
                receiverIds.removeIf(id -> id.equals(2L) || id.equals(message.getSenderId()));
                // 遍历 receiverIds 中的每个 receiverId
                boolean allAnnouncementUsersCreated = true; // 用于标记是否所有关联都创建成功
                for (Long receiverId : receiverIds) {
                    boolean announcementUser = createAnnouncementUser(message.getId(), receiverId);
                    // 可以在这里处理 announcementUser 的返回值，例如记录日志等
                    if (announcementUser) {
                        log.info("为{}成功创建公告用户:" ,receiverId);
                    } else {
                        log.info("为{}创建公告用户失败： " , receiverId);
                        allAnnouncementUsersCreated = false; // 如果有一个失败，标记为 false
                    }
                }
                if (!allAnnouncementUsersCreated) {
                    announcementMapper.updateAnnouncementStatus(message.getId(), "FAILED");
                    throw new BusinessException(500, "创建消息关联失败，请检查接收者ID是否正确");
                }
                try {
                    messagingTemplate.convertAndSend("/topic/broadcast", message);
                } catch (Exception e) {
                    log.error("广播消息发送失败", e);
                    throw new BusinessException(500, "广播消息发送失败，请稍后重试");
                }
                announcementMapper.updateAnnouncementStatus(message.getId(), "PUBLISHED");
                return ResponseEntity.ok(ApiResponseMe.success("广播消息发送成功"));
            }
            //私聊模式
            if (message.getReceiverIds().size() == 1) {
                Long receiverId = message.getReceiverIds().get(0);
                log.info("单发消息: 从 {} 到 {}", message.getSenderId(), receiverId);
                log.info("单发消息: {}", message);
                // 创建关联
                Boolean announcementUser = createAnnouncementUser(message.getId(), receiverId);
                if (!announcementUser) {
                    announcementMapper.updateAnnouncementStatus(message.getId(), "FAILED");
                    throw new BusinessException(500, "创建消息关联失败，请检查接收者ID是否正确");
                }

                try {
                    messagingTemplate.convertAndSendToUser(
                            receiverId.toString(),
                            "/queue/private",
                            message
                    );
                } catch (Exception e) {
                    log.error("私聊消息发送失败", e);
                    throw new BusinessException(500, "消息发送失败，接收者可能已离线");
                }

                announcementMapper.updateAnnouncementStatus(message.getId(), "PUBLISHED");
                return ResponseEntity.ok(ApiResponseMe.success("私聊消息发送成功"));
            } else {
                // 群发消息处理
                log.info("群发消息: 从 {} 到 {} 个接收者", message.getSenderId(), message.getReceiverIds().size());
                log.info("接收者{}",message.getReceiverIds());
                List<Long> failedReceivers = new ArrayList<>();
                
                for (Long receiverId : message.getReceiverIds()) {
                    try {
                        // 创建关联
                        Boolean announcementUser = createAnnouncementUser(message.getId(), receiverId);
                        if (!announcementUser) {
                            failedReceivers.add(receiverId);
                            continue;
                        }

                        messagingTemplate.convertAndSendToUser(
                                receiverId.toString(),
                                "/queue/private",
                                message
                        );
                    } catch (Exception e) {
                        log.error("群发消息发送失败，接收者ID: {}", receiverId, e);
                        failedReceivers.add(receiverId);
                    }
                }

                if (!failedReceivers.isEmpty()) {
                    announcementMapper.updateAnnouncementStatus(message.getId(), "PARTIAL");
                    throw new BusinessException(500, String.format("部分消息发送失败，失败的接收者ID: %s", failedReceivers));
                }
                announcementMapper.updateAnnouncementStatus(message.getId(), "PUBLISHED");
                return ResponseEntity.ok(ApiResponseMe.success("群发消息发送成功"));
            }
        } catch (BusinessException e) {
            log.error("业务处理异常", e);
            announcementMapper.updateAnnouncementStatus(message.getId(), "FAILED");
            throw e;
        } catch (Exception e) {
            log.error("系统异常", e);
            announcementMapper.updateAnnouncementStatus(message.getId(), "FAILED");
            throw new BusinessException(500, "系统处理异常，请稍后重试");
        }
    }
    
    private Boolean createAnnouncementUser(Long announcementId, Long userId) {
        if (announcementId == null || userId == null) {
            log.warn("创建关联失败：公告ID或用户ID为空");
            return false;
        }
        try {
            return announcementMapper.createAnnouncementUser(announcementId, userId) == 1;
        } catch (Exception e) {
            log.error("创建关联数据库操作失败", e);
            return false;
        }
    }
}